"""
通知服务数据模型
================

提供通知服务的数据模型定义
"""

# 确保项目根目录在Python路径中

# 统一路径管理
from backend.shared import PathManager
PathManager().setup_paths()
import sys
import os

from pydantic import BaseModel, EmailStr, validator
from typing import Optional, List, Dict, Any
from datetime import datetime
from enum import Enum

class NotificationType(str, Enum):
    """通知类型"""
    EMAIL = "email"
    SMS = "sms"
    PUSH = "push"
    WEBSOCKET = "websocket"
    WEBHOOK = "webhook"

class NotificationStatus(str, Enum):
    """通知状态"""
    PENDING = "pending"
    SENT = "sent"
    DELIVERED = "delivered"
    FAILED = "failed"
    CANCELLED = "cancelled"

class NotificationPriority(str, Enum):
    """通知优先级"""
    LOW = "low"
    NORMAL = "normal"
    HIGH = "high"
    URGENT = "urgent"

# 基础通知模型

class BaseNotification(BaseModel):
    """基础通知模型"""
    user_id: str
    title: str
    content: str
    priority: NotificationPriority = NotificationPriority.NORMAL
    metadata: Optional[Dict[str, Any]] = None
    scheduled_at: Optional[datetime] = None
    expires_at: Optional[datetime] = None

# 邮件通知模型

class EmailNotification(BaseNotification):
    """邮件通知模型"""
    recipient_email: EmailStr
    sender_email: Optional[EmailStr] = None
    sender_name: Optional[str] = None
    html_content: Optional[str] = None
    attachments: Optional[List[str]] = None
    
    @validator('title')
    def validate_title(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('邮件标题不能为空')
        return v.strip()

# 短信通知模型

class SMSNotification(BaseNotification):
    """短信通知模型"""
    recipient_phone: str
    sender_name: Optional[str] = None
    template_id: Optional[str] = None
    template_params: Optional[Dict[str, str]] = None
    
    @validator('recipient_phone')
    def validate_phone(cls, v):
        # 简单的手机号验证
        if not v or len(v.strip()) < 10:
            raise ValueError('手机号格式不正确')
        return v.strip()
    
    @validator('content')
    def validate_content_length(cls, v):
        if len(v) > 500:
            raise ValueError('短信内容不能超过500字符')
        return v

# 推送通知模型

class PushNotification(BaseNotification):
    """推送通知模型"""
    device_tokens: List[str]
    badge_count: Optional[int] = None
    sound: Optional[str] = "default"
    category: Optional[str] = None
    action_data: Optional[Dict[str, Any]] = None
    image_url: Optional[str] = None
    
    @validator('device_tokens')
    def validate_device_tokens(cls, v):
        if not v or len(v) == 0:
            raise ValueError('设备令牌不能为空')
        return v

# WebSocket通知模型

class WebSocketNotification(BaseNotification):
    """WebSocket通知模型"""
    channel: str
    event_type: str
    broadcast: bool = False
    target_users: Optional[List[str]] = None
    
    @validator('channel')
    def validate_channel(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('频道名称不能为空')
        return v.strip()

# Webhook通知模型

class WebhookNotification(BaseNotification):
    """Webhook通知模型"""
    webhook_url: str
    http_method: str = "POST"
    headers: Optional[Dict[str, str]] = None
    payload: Optional[Dict[str, Any]] = None
    retry_count: int = 3
    timeout: int = 30
    
    @validator('webhook_url')
    def validate_webhook_url(cls, v):
        if not v or not v.startswith(('http://', 'https://')):
            raise ValueError('Webhook URL格式不正确')
        return v
    
    @validator('http_method')
    def validate_http_method(cls, v):
        if v.upper() not in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']:
            raise ValueError('不支持的HTTP方法')
        return v.upper()

# 通知响应模型

class NotificationResponse(BaseModel):
    """通知响应模型"""
    notification_id: str
    status: NotificationStatus
    message: str
    created_at: datetime
    sent_at: Optional[datetime] = None
    delivered_at: Optional[datetime] = None
    error_message: Optional[str] = None
    retry_count: int = 0
    
    class Config:
        from_attributes = True

# 通知历史模型

class NotificationHistory(BaseModel):
    """通知历史模型"""
    id: str
    user_id: str
    notification_type: NotificationType
    title: str
    content: str
    status: NotificationStatus
    priority: NotificationPriority
    recipient: str
    created_at: datetime
    sent_at: Optional[datetime] = None
    delivered_at: Optional[datetime] = None
    error_message: Optional[str] = None
    retry_count: int = 0
    metadata: Optional[Dict[str, Any]] = None
    
    class Config:
        from_attributes = True

# 批量通知模型

class BatchNotificationRequest(BaseModel):
    """批量通知请求模型"""
    notification_type: NotificationType
    title: str
    content: str
    priority: NotificationPriority = NotificationPriority.NORMAL
    recipients: List[str]
    template_id: Optional[str] = None
    template_params: Optional[Dict[str, Any]] = None
    scheduled_at: Optional[datetime] = None
    metadata: Optional[Dict[str, Any]] = None
    
    @validator('recipients')
    def validate_recipients(cls, v):
        if not v or len(v) == 0:
            raise ValueError('收件人列表不能为空')
        if len(v) > 1000:
            raise ValueError('批量通知收件人不能超过1000个')
        return v

class BatchNotificationResponse(BaseModel):
    """批量通知响应模型"""
    batch_id: str
    total_count: int
    success_count: int
    failed_count: int
    notifications: List[NotificationResponse]
    created_at: datetime

# 通知模板模型

class NotificationTemplate(BaseModel):
    """通知模板模型"""
    id: str
    name: str
    notification_type: NotificationType
    title_template: str
    content_template: str
    variables: List[str]
    is_active: bool = True
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True

class TemplateCreateRequest(BaseModel):
    """模板创建请求"""
    name: str
    notification_type: NotificationType
    title_template: str
    content_template: str
    variables: Optional[List[str]] = None
    
    @validator('name')
    def validate_name(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('模板名称不能为空')
        return v.strip()

class TemplateUpdateRequest(BaseModel):
    """模板更新请求"""
    name: Optional[str] = None
    title_template: Optional[str] = None
    content_template: Optional[str] = None
    variables: Optional[List[str]] = None
    is_active: Optional[bool] = None

# 通知统计模型

class NotificationStats(BaseModel):
    """通知统计模型"""
    total_sent: int
    total_delivered: int
    total_failed: int
    delivery_rate: float
    failure_rate: float
    avg_delivery_time: Optional[float] = None
    stats_by_type: Dict[str, Dict[str, int]]
    stats_by_priority: Dict[str, Dict[str, int]]
    recent_errors: List[str]

# 用户通知设置模型

class UserNotificationSettings(BaseModel):
    """用户通知设置模型"""
    user_id: str
    email_enabled: bool = True
    sms_enabled: bool = True
    push_enabled: bool = True
    websocket_enabled: bool = True
    
    # 按类型的设置
    trading_notifications: bool = True
    risk_notifications: bool = True
    system_notifications: bool = True
    marketing_notifications: bool = False
    
    # 时间设置
    quiet_hours_start: Optional[str] = None  # HH:MM格式
    quiet_hours_end: Optional[str] = None    # HH:MM格式
    timezone: str = "UTC"
    
    class Config:
        from_attributes = True

class UserNotificationSettingsUpdate(BaseModel):
    """用户通知设置更新模型"""
    email_enabled: Optional[bool] = None
    sms_enabled: Optional[bool] = None
    push_enabled: Optional[bool] = None
    websocket_enabled: Optional[bool] = None
    trading_notifications: Optional[bool] = None
    risk_notifications: Optional[bool] = None
    system_notifications: Optional[bool] = None
    marketing_notifications: Optional[bool] = None
    quiet_hours_start: Optional[str] = None
    quiet_hours_end: Optional[str] = None
    timezone: Optional[str] = None

# 设备注册模型

class DeviceRegistration(BaseModel):
    """设备注册模型"""
    user_id: str
    device_token: str
    device_type: str  # ios, android, web
    app_version: str
    device_info: Optional[Dict[str, Any]] = None
    
    @validator('device_token')
    def validate_device_token(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('设备令牌不能为空')
        return v.strip()
    
    @validator('device_type')
    def validate_device_type(cls, v):
        if v not in ['ios', 'android', 'web']:
            raise ValueError('不支持的设备类型')
        return v

class DeviceInfo(BaseModel):
    """设备信息模型"""
    id: str
    user_id: str
    device_token: str
    device_type: str
    app_version: str
    device_info: Optional[Dict[str, Any]] = None
    is_active: bool = True
    last_seen: datetime
    created_at: datetime
    
    class Config:
        from_attributes = True